package com.urbo.android.shortcutter;

import java.lang.ref.SoftReference;
import java.util.LinkedList;
import java.util.List;

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

/**
 * @author radovan.urban@gmail.com
 */
public class ResImageAdapter extends BaseAdapter {

	/* Some devices with very limited memory and some shitty ones like HTC Desire HD have problem to display more than 
	   about 400 icons when simple List<Drawable> is used. This workaround implements image cache with SoftReference to
	   allow garbage collector free this resources as first. Unfortunately it cause jerky motion when scrolling through icons,
	   because it seems that garbage collector eats references immediately when GridView frees invisible row. 
	   So the performance improvement compare to basic resource loading in getView is just few percent. But as an example
	   of using SoftReference as the cache, it's good to keep the code here.
	*/ 
	
	/* There is no measurable difference between WeakReference and SoftReference in this case. */

	static class IconCache {
		private List<SoftReference<Drawable>>icons = new LinkedList<SoftReference<Drawable>>();
		private List<Integer>iconResources = new LinkedList<Integer>();
		private List<String>iconPackages = new LinkedList<String>();	// when application icon is chose, icon can come from different packages
		//private int a = 0;
		PackageManager packageManager;
		Resources ipackRes;
		
		public Drawable get(int position) {
			Drawable value = (Drawable)icons.get( position ).get();
			if (value == null) {
				//a++;
				//if( a % 10==0 ){
				//	Log.d( "JA", String.valueOf( a ) );
				//}
				try{ ipackRes = packageManager.getResourcesForApplication(iconPackages.get( position ) );} catch(Exception e){}
				value  = ipackRes.getDrawable( iconResources.get( position ) );
				icons.set( position, new SoftReference<Drawable>( value ) );
			} 
			return value;
		}

		public void put(Context context, String packageName, int iconResource) {
			this.packageManager = context.getPackageManager();
			
			try{ ipackRes = packageManager.getResourcesForApplication(packageName);}
			catch(Exception e) {}
			
			iconResources.add(iconResource);
			iconPackages.add(packageName);
			
			// Fast start of adapter. slow scrolling
			//icons.add(new SoftReference<Drawable>(null)); 
			
			// Slow start faster scrolling
			 icons.add(new SoftReference<Drawable>(ipackRes.getDrawable(Integer.valueOf(iconResource))));
		}
		
		public void clear(){
			icons.clear();
			iconResources.clear();
			iconPackages.clear();
		}
		
		public int getCount(){
			return icons.size();
		}
	}
	
	private Context mContext;
	private IconCache mListOfImages;
	private int mImageViewResource;
	private int mImageViewItemResource;
	private LayoutInflater mInflater;

	public static String ITEM_PACKAGE_NAME = "package_name";
	public static String ITEM_RESOURCE_ID = "resource_id";
	public static String ITEM_TITLE = "title";
	
	public ResImageAdapter(Context context, IconCache listOfImages, int imageViewResource, int imageViewIemResource ){
		this.mContext = context;
		this.mListOfImages = listOfImages;
		this.mImageViewResource = imageViewResource;
		this.mImageViewItemResource = imageViewIemResource;
		this.mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}
	
	@Override
	public int getCount() {
		return mListOfImages.getCount();
	}

	@Override
	public Object getItem(int position) {
		return mListOfImages.get(position);
	}

	// Position in list is also unique id
	@Override
	public long getItemId(int position) {
		return position;
	}

	static class ViewHolder {
		ImageView icon;
	}
	
	public void clear(){
		mListOfImages.clear();
		this.notifyDataSetChanged();
	}
	
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		ViewHolder holder;
		
		if (convertView == null) {  // if it's not recycled
		
			holder = new ViewHolder();
			convertView = mInflater.inflate(mImageViewResource, null);
			holder.icon = (ImageView)convertView.findViewById(mImageViewItemResource);
			convertView.setTag( holder );
			
		} else { // use passed View
			holder = (ViewHolder) convertView.getTag();
		}

		holder.icon.setImageDrawable(mListOfImages.get(position));
		
		return convertView;
	}
}
